/*
 * @Author: zhouwei wei.zhou@flip.fun
 * @Date: 2024-04-02 20:09:57
 * @LastEditors: zhouwei wei.zhou@flip.fun
 * @LastEditTime: 2024-04-07 15:45:20
 * @FilePath: /50/手撕系列/new.js
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
/**
 * @args 第一个参数是构造函数
 * @args 剩余的参数是实例化对象的传入的参数
 * @description 模拟new操作符
 * 具体实现
 * （1）首先创建了一个新的空对象
 * （2）设置原型，将对象的原型设置为函数的 prototype 对象。
 * （3）让函数的 this 指向这个对象，执行构造函数的代码（为这个新对象添加属性）
 * （4）判断函数的返回值类型，如果是值类型，返回创建的对象。如果是引用类型，就返回这个引用类型的对象。
 */
function newFn() {
	// 拿到构造函数
	const contructor = Array.prototype.shift.call(arguments)
	if (typeof contructor !== 'function') {
		throw new Error('请传入函数')
	}
	// 创建一个新建对象,并且让这个对象的隐式原型指向构造函数的原型对象
	const newObj = Object.create(contructor.prototype)
	// 给newObj添加属性
	let result = contructor.apply(newObj, arguments)
	/**
	 * 这里的下面的具体逻辑
	 * 1. 如果构造函数的返回值是一个对象,应该返回的是这个对象
	 * 2. 否则返回新建对象
	 */
	if (result && ['function', 'object'].includes(typeof result)) {
		return result
	}
	return newObj
}
const res = newFn(function (name) {
	this.name = name
	return []
}, 'zs')
console.log(res)
